package com.example.springboot.Interceptor;

import com.example.springboot.annotation.MethodPermission;
import com.example.springboot.common.system.UserHolder;
import com.example.springboot.common.utils.StringUtils.StringUtils;
import com.example.springboot.common.utils.ThrowUtil.ThrowUtil;
import com.example.springboot.entity.LoginUser;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;

import static com.example.springboot.common.constants.Constants.FORBIDDEN;
import static com.example.springboot.common.constants.Constants.UNAUTHORIZED;

@Component
public class PermissionInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        //校验登录对象是否过期
        LoginUser loginUser = UserHolder.getLoginUser();
        ThrowUtil.throwIf(StringUtils.isNull(loginUser), "登录过期请重新登录", UNAUTHORIZED);
        //校验权限
        //检查处理程序是否为 HandlerMethod 的实例
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //检查方法是否标记了 MethodPermission 注解
        if (!method.isAnnotationPresent(MethodPermission.class)) {
            return true;
        }
        MethodPermission methodPermission = method.getAnnotation(MethodPermission.class);
        List<String> permissions = loginUser.getPermissions();
        ThrowUtil.throwIf(permissions == null || permissions.isEmpty(), "无权限，请联系管理员授权", FORBIDDEN);
        //如果没权限,直接抛异常,让全局业务异常捕获器捕获,返回对应的状态码
        ThrowUtil.throwIf(!hasThisPrivilege(permissions, methodPermission.value()), "无权限，请联系管理员授权", FORBIDDEN);
        return true;
    }

    public boolean hasThisPrivilege(List<String> strPrivilege, String privilegeCode) {
        return strPrivilege.contains(privilegeCode);
    }
}
